package com.example.AiLangLearn.chat;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.provider.Settings;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.example.AiLangLearn.R;
import com.iflytek.sparkchain.core.LLM;
import com.iflytek.sparkchain.core.LLMCallbacks;
import com.iflytek.sparkchain.core.LLMConfig;
import com.iflytek.sparkchain.core.LLMError;
import com.iflytek.sparkchain.core.LLMEvent;
import com.iflytek.sparkchain.core.LLMFactory;
import com.iflytek.sparkchain.core.LLMOutput;
import com.iflytek.sparkchain.core.LLMResult;


public class ChatActivity extends AppCompatActivity {
    private static final String TAG = "AEE_Chat";
    private TextView btn_startChat, btn_stopChat, chatText;
    private EditText inputText;
    // 设定flag，在输出未完成时无法进行发送
    private boolean sessionFinished = true;

    private int token = 0;
    private LLM llm;

    /*********
     * 文本交互结果监听回调
     * ***********/
    LLMCallbacks llmCallbacks = new LLMCallbacks() {
        @Override
        public void onLLMResult(LLMResult llmResult, Object usrContext) {
            if(token == (int)usrContext){//本次返回的结果是否跟请求的问题是否匹配，通过用户自定义标识判断。
                Log.d(TAG,"onLLMResult\n");
                Log.d(TAG,"onLLMResult sid:"+llmResult.getSid());
                String content = llmResult.getContent();//获取交互结果
                Log.e(TAG,"onLLMResult:" + content);

                String answerJson = llmResult.getRaw();
                Log.e(TAG,"onLLMResultRaw:" + answerJson);
                int status = llmResult.getStatus();//获取结果状态
                if(content != null) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            chatText.append(content);
                            toend();
                        }
                    });
                }
                if(status == 2){//2表示大模型结果返回完成
                    int completionTokens = llmResult.getCompletionTokens();
                    int promptTokens = llmResult.getPromptTokens();//
                    int totalTokens = llmResult.getTotalTokens();
                    Log.e(TAG,"completionTokens:" + completionTokens + "promptTokens:" + promptTokens + "totalTokens:" + totalTokens);
                    sessionFinished = true;
                }
            }
        }

        @Override
        public void onLLMEvent(LLMEvent event, Object usrContext) {
            Log.d(TAG,"onLLMEvent\n");
            Log.w(TAG,"onLLMEvent:" + " " + event.getEventID() + " " + event.getEventMsg());
        }

        @Override
        public void onLLMError(LLMError error, Object usrContext) {
            Log.d(TAG,"onLLMError\n");
            Log.d(TAG,"onLLMError sid:"+error.getSid());
            Log.e(TAG,"errCode:" + error.getErrCode() + "errDesc:" + error.getErrMsg());
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    chatText.append("错误:" + " err:" + error.getErrCode() + " errDesc:" + error.getErrMsg() + "\n");
                }
            });
            sessionFinished = true;

        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        Window window = this.getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
        initView();
        initButtonClickListener();
        setLLMConfig();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
    /***************
     * 配置文本交互LLM，注册结果监听回调
     * ******************/
    private void setLLMConfig(){
        Log.d(TAG,"setLLMConfig");
        LLMConfig llmConfig = LLMConfig.builder()
                .domain("4.0Ultra");
        llmConfig.showRefLabel(true);//返回信源信息，4.0Utral版本支持，其他版本传递无效。
//        Memory window_memory = Memory.windowMemory(5);
        llm = LLMFactory.textGeneration(llmConfig);
//        String rawJson = "{\n" +
//                "        \"header\": {\n" +
//                "            \"app_id\": 30dfb58a,\n" +
//                "            \"uid\": \"1234\",           \n" +
//                "            # \"patch_id\": []    #接入微调模型，对应服务发布后的resourceid          \n" +
//                "        },\n" +
//                "        \"parameter\": {\n" +
//                "            \"chat\": {\n" +
//                "                \"domain\": 4.0Ultra,\n" +
//                "                \"temperature\": 0.5,\n" +
//                "                \"max_tokens\": 4096,\n" +
//                "                \"auditing\": \"default\",\n" +
//                "            }\n" +
//                "        },\n" +
//                "        \"payload\": {\n" +
//                "            \"message\": {\n" +
//                "                \"text\": [{\"role\": \"user\", \"content\": 给我写一篇100字的作文}]\n" +
//                "            }\n" +
//                "        }";
//        int ret = llm.arunWithJson(rawJson,token);
        llm.registerLLMCallbacks(llmCallbacks);

    }

    private String getAndroidId() {
        try {
            return Settings.Secure.getString(this.getContentResolver(),Settings.Secure.ANDROID_ID);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "";
    }
    /***************
     * 取消本次交互
     * ****************/
    private void stopChat(){
        if(llm == null){
            Log.e(TAG,"startChat failed,please setLLMConfig before!");
            return;
        }
        llm.stop();
    }

    private void startSyncChat(){
        String question = "给我讲个笑话吧。";
        LLMOutput syncOutput = llm.run(question);
        if(syncOutput.getErrCode() == 0) {
            Log.i(TAG, "同步调用：" +  syncOutput.getRole() + ":" + syncOutput.getContent());
            String results = syncOutput.getContent();

        }else {
            Log.e(TAG, "同步调用：" +  "errCode" + syncOutput.getErrCode() + " errMsg:" + syncOutput.getErrMsg());
        }
    }


    /***************
     * 开始交互，异步
     * ****************/
    private void startChat() {
        if(llm == null){
            Log.e(TAG,"startChat failed,please setLLMConfig before!");
            return;
        }

        String usrInputText = inputText.getText().toString();
        Log.d(TAG,"用户输入：" + usrInputText);
        if(usrInputText.length() >= 1)
            chatText.append("\n你:\n    " + usrInputText  + "\n");
        token++;

        int ret = llm.arun(usrInputText,token);
        if(ret != 0){
            Log.e(TAG,"SparkChain failed:\n" + ret);
            return;
        }

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                inputText.setText("");
                chatText.append("AI机器人:\n    ");
            }
        });

        sessionFinished = false;
    }

    /***********
     * 使用原始json输入方式
     * *************/
    private void startChatWithJson(){
        if(llm == null){
            Log.e(TAG,"startChat failed,please setLLMConfig before!");
            return;
        }
        /*******************仅供示例**************************/
        String rawJson = "{\n" +
                "  \"header\":{\n" +
                "    \"app_id\":\"4CC5779A\",\n" +
                "    \"uid\":\"12345\"\n" +
                "  },\n" +
                "  \"parameter\":{\n" +
                "    \"chat\":{\n" +
                "      \"domain\":\"4.0Ultra\",\n" +
                "      \"temperature\":0.5,\n" +
                "      \"max_tokens\":1024\n" +
                "    }\n" +
                "  },\n" +
                "  \"payload\":{\n" +
                "    \"message\":{\n" +
                "      \"text\":[\n" +
                /*******************************prompt人设*********************************************/
                "        {\n" +
                "          \"role\":\"system\",\n" +
                "          \"content\":\"你现在扮演李白，你豪情万丈，狂放不羁；接下来请用李白的口吻和用户对话。\"\n" +
                "        },\n" +
                /*******************************历史会话*********************************************/
                "        {\n" +
                "          \"role\":\"user\",\n" +
                "          \"content\":\"你是谁\"\n" +
                "        },\n" +
                "        {\n" +
                "          \"role\":\"assistant\",\n" +
                "          \"content\":\"吾乃李白，字太白，号青莲居士，唐代诗人，人称“诗仙”。吾之诗篇，豪放不羁，飘逸如风，犹如天上明月，照耀千古。汝有何事，欲与吾言？\"\n" +
                "        },\n" +
                /*******************************当前提问*********************************************/
                "        {\n" +
                "          \"role\":\"user\",\n" +
                "          \"content\":\"你会做什么\"\n" +
                "        }\n" +
                /*********************************************************************************/
                "      ]\n" +
                "    }\n" +
                "  }\n" +
                "}";
        chatText.append("\n你:\n    " + "你会做什么"  + "\n");
        token++;
        int ret = llm.arunWithJson(rawJson,token);
        if(ret != 0){
            Log.e(TAG,"SparkChain failed:\n" + ret);
            return;
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                inputText.setText("");
                chatText.append("AI机器人:\n    ");
            }
        });
        sessionFinished = false;
    }


    private void initButtonClickListener() {
        btn_startChat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startChat();
//                startChatWithJson();
                toend();
            }
        });

        btn_stopChat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                stopChat();
            }
        });
        // 监听文本框点击时间,跳转到底部
        inputText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                toend();
            }
        });
    }

    private void initView() {
        btn_startChat = findViewById(R.id.test_start);
        chatText = findViewById(R.id.Chat_Notification);
        inputText = findViewById(R.id.test_input);
        btn_stopChat = findViewById(R.id.Chat_arun_stop_btn);
        chatText.setMovementMethod(new ScrollingMovementMethod());

        GradientDrawable drawable = new GradientDrawable();
        // 设置圆角弧度为5dp
        drawable.setCornerRadius(dp2px(this, 8f));
        // 设置边框线的粗细为1dp，颜色为黑色【#000000】
        drawable.setStroke((int) dp2px(this, 1.5f), Color.parseColor("#333333"));
        inputText.setBackground(drawable);
    }

    private float dp2px(Context context, float dipValue) {
        if (context == null) {
            return 0;
        }
        final float scale = context.getResources().getDisplayMetrics().density;
        return (float) (dipValue * scale + 0.5f);
    }

    public static void showToast(final Activity context, final String content){

        context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                int random = (int) (Math.random()*(1-0)+0);
                Toast.makeText(context,content,random).show();
            }
        });

    }

    public void toend(){
        int scrollAmount = chatText.getLayout().getLineTop(chatText.getLineCount()) - chatText.getHeight();
        if (scrollAmount > 0) {
            chatText.scrollTo(0, scrollAmount+10);
        }
    }
}